<template>
  <div>
    <div>
      <el-card v-show="contactVisible">
        <!-- // 面包屑 -->
        <div>
          <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/index' }"
              >首页</el-breadcrumb-item
            >
            <el-breadcrumb-item>测试用例</el-breadcrumb-item>
          </el-breadcrumb>
        </div>
        <br />

        <!-- // 查询 -->
        <el-form
          label-width="80px"
          :inline="true"
          :model="queryForm"
          class="query-form-inline"
          size="small"
        >
          <el-form-item label="用例名称">
            <el-input
              v-model="queryForm.name"
              placeholder="请输入用例名称"
              clearable
            ></el-input>
          </el-form-item>
          <el-form-item label="用例标签">
            <el-select clearable v-model="queryForm.tag" placeholder="用例标签">
              <el-option
                v-for="item in caseTag"
                :key="item.label"
                :label="item.label"
                :value="item.value"
              >
              </el-option>
            </el-select>
          </el-form-item>

          <el-form-item>
            <el-button type="primary" @click="loadCase">查询</el-button>
            <el-button type="success" @click="handleAddCase">新增</el-button>
          </el-form-item>

          <!-- // 环境变量 -->
          <el-form-item class="config" style="margin-left:100px">
            <el-select
              v-model="currentConfigId"
              placeholder="Environment"
              style="width:200px"
              clearable
              @change="handleChangeConfig"
            >
              <el-option
                v-for="item in configData"
                :key="item.name"
                :label="item.name"
                :value="item.id"
              ></el-option>
            </el-select>
            <el-button
              icon="el-icon-share"
              circle
              plain
              style="padding-left:10px; border:None;"
              @click="configVisible = true"
            >
            </el-button>
          </el-form-item>

          <!-- // 环境变量弹窗 -->
          <el-dialog
            title="环境变量"
            :visible.sync="configVisible"
            :modal-append-to-body="false"
            width="1100px"
            center
          >
            <config ref="config" :loading="loading"></config>
            <div slot="footer" class="copy-footer">
              <el-button type="" @click="configVisible = false" size="small"
                >取 消
              </el-button>
              <el-button type="primary" @click="handleConfig" size="small"
                >确 定
              </el-button>
            </div>
          </el-dialog>
        </el-form>

        <el-container>
          <!-- // 分组按钮 -->
          <el-aside width="168px" style="margin-top:18px">
            <div>
              <el-button
                circle
                icon="el-icon-circle-plus-outline"
                size="mini"
                type="primary"
                @click="handleAddGroup"
                style="margin-left:18px;border:None;"
              ></el-button>
              <el-button
                icon="el-icon-edit"
                circle
                :disabled="disable"
                type="success"
                size="mini"
                @click="handleEditGroup"
                style="margin-left:18px;border:None;"
              ></el-button>
              <el-button
                icon="el-icon-delete"
                circle
                :disabled="disable"
                type="danger"
                size="mini"
                @click="deleteGroup(groupForm.id)"
                style="margin-left:18px;border:None;"
              ></el-button>
              <br />
              <br />
            </div>

            <!-- // 左侧分组 -->
            <el-tree
              ref="tree"
              :data="treeData"
              :props="defaultProps"
              node-key="id"
              highlight-current
              accordion
              @node-click="handleNodeClick"
            >
            </el-tree>
          </el-aside>

          <!-- // 表格数据 -->
          <el-main>
            <el-table
              border
              size="medium"
              :data="tableData"
              tooltip-effect="dark"
              style="width: 100%"
            >
              <el-table-column
                label="ID"
                prop="id"
                width="50"
              ></el-table-column>

              <el-table-column
                label="用例名称"
                show-overflow-tooltip
                prop="name"
                width="260"
              >
              </el-table-column>
              <el-table-column
                label="用例描述"
                show-overflow-tooltip
                prop="desc"
              >
              </el-table-column>
              <el-table-column label="用例标签" width="110">
                <template slot-scope="scope">
                  <el-tag type="primary" effect="plain">
                    {{
                      scope.row.tag == 1
                        ? caseTag[0].label
                        : scope.row.tag == 2
                        ? caseTag[1].label
                        : caseTag[2].label
                    }}
                  </el-tag>
                </template>
              </el-table-column>
              <el-table-column label="环境" width="80">
                <template slot-scope="scope">
                  <el-tag :type="caseEnv[scope.row.env].type" effect="plain">
                    {{ caseEnv[scope.row.env].label }}
                  </el-tag>
                </template>
              </el-table-column>

              <el-table-column label="执行次数" width="80" prop="count">
              </el-table-column>
              <el-table-column
                label="执行结果"
                show-overflow-tooltip
                width="80"
                prop="result"
              >
                <template slot-scope="scope">
                  <el-tag
                    size="medium"
                    :type="
                      scope.row.result == 1
                        ? 'success'
                        : scope.row.result == 0
                        ? 'danger'
                        : 'primary'
                    "
                  >
                    {{ caseResult[scope.row.result] }}
                  </el-tag>
                </template>
              </el-table-column>

              <el-table-column label="创建人" width="100" prop="creator">
                <template slot-scope="scope">
                  <el-tag type="primary" effect="plain" size="medium">
                    {{ scope.row.creator }}
                  </el-tag>
                </template>
              </el-table-column>

              <el-table-column label="更新人" width="100" prop="updator">
                <template slot-scope="scope">
                  <el-tag type="primary" effect="plain" size="medium">
                    {{ scope.row.updator }}
                  </el-tag>
                </template>
              </el-table-column>

              <el-table-column
                label="更新时间"
                width="160"
                prop="update_time"
                :formatter="dateFormat"
              >
              </el-table-column>

              <el-table-column label="操作" width="300" fixed="right">
                <template slot-scope="scope">
                  <el-button
                    size="mini"
                    @click="handleonEditCase(scope.$index, scope.row)"
                    type="primary"
                    >编辑
                  </el-button>
                  <el-button size="mini" @click="contactCase(scope.row)" type=""
                    >关联
                  </el-button>
                  <el-button
                    size="mini"
                    @click="runCase(scope.$index, scope.row)"
                    type="success"
                    plain
                    >运行
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    @click="handleDeleteCase(scope.row.id)"
                    >删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>

            <br />
            <!-- 分页 -->
            <el-pagination
              background
              :page-size="pagination.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              @size-change="handleSizeChange"
              :page-sizes="[12, 20, 50, 100]"
              :total="pagination.total"
              :current-page.sync="pagination.page"
              @current-change="loadCase(pagination.page, groupId)"
            >
            </el-pagination>
          </el-main>
        </el-container>
      </el-card>

      <el-card v-if="!contactVisible" style="padding: 0; height: 830px">
        <contact
          @changeContract="handleContract"
          :case-id="caseId"
          :contactList="contactList"
        ></contact>
      </el-card>
    </div>

    <!-- // 添加用例弹窗表单 -->
    <el-dialog
      :title="addCaseTitle"
      :visible.sync="addCaseVisible"
      :modal-append-to-body="false"
      :close-on-click-modal="false"
      :close-on-press-escape="false"
    >
      <div>
        <el-form
          :model="addCaseForm"
          :rules="addCaseFormrules"
          ref="addCaseForm"
          class="form-inline"
        >
          <el-form-item prop="name">
            <el-input
              v-model="addCaseForm.name"
              placeholder="名称尽量保持其唯一性，方便识别"
              size="small"
            >
              <template slot="prepend">用例名称</template>
            </el-input>
          </el-form-item>
          <el-form-item prop="desc">
            <el-input
              v-model="addCaseForm.desc"
              placeholder="请输入用例描述信息"
              size="small"
            >
              <template slot="prepend">用例描述</template>
            </el-input>
          </el-form-item>
        </el-form>
        <div>
          <el-form :inline="true" :model="addCaseForm" class="form-inline2">
            <el-form-item label="用例标签" prop="tag">
              <el-select border v-model="addCaseForm.tag" size="small">
                <el-option
                  v-for="item in caseTag"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="用例环境" prop="env">
              <el-select
                v-model="addCaseForm.env"
                placeholder="请选择"
                size="small"
              >
                <el-option
                  v-for="item in caseEnv"
                  :key="item.value"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="环境变量" prop="config_id">
              <el-select
                v-model="addCaseForm.config_id"
                placeholder="请选择"
                size="small"
              >
                <el-option
                  v-for="(item, index) in configData"
                  :key="index"
                  :name="item.id"
                  :value="item.id"
                  :label="item.name"
                >
                </el-option>
              </el-select>
            </el-form-item>
          </el-form>
        </div>
      </div>
      <div slot="" footerclass="dialog-footer">
        <el-button @click="addCaseVisible = false" size="small"
          >取 消
        </el-button>
        <el-button type="primary" @click="submitCaseForm" size="small"
          >确 定
        </el-button>
      </div>
    </el-dialog>

    <!-- 添加分组弹窗 -->
    <el-dialog
      :title="groupFormTitle"
      :visible.sync="groupFormVisible"
      :modal-append-to-body="false"
      width="25%"
    >
      <el-form :inline="true" :model="groupForm" class="demo-form-inline">
        <el-form-item label="分组名称" label-width="100px">
          <el-input
            v-model="groupForm.name"
            placeholder="请输入分组名称"
            style="width:250px"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="groupFormVisible = false" size="small"
          >取 消
        </el-button>
        <el-button type="primary" @click="submitGroupForm" size="small"
          >确 定
        </el-button>
      </div>
    </el-dialog>

    <!-- // 运行接口结果弹窗 -->
    <el-dialog
      :visible.sync="reportVisible"
      :modal-append-to-body="false"
      :close-on-click-modal="false"
      width="1300px"
      center
    >
      <report :result="result"></report>

      <div slot="footer" class="copy-footer">
        <el-button type="primary" @click="reportVisible = false" size="small"
          >确 定
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import Config from "@/views/interface/components/config";
import Report from "@/views/interface/components/report";
import Contact from "./components/contact";
import {
  addCase,
  updateCase,
  queryCase,
  deleteCase,
  queryConnect
} from "@/api/case";
import { addGroup, updateGroup, queryGroup, deleteGroup } from "@/api/group";
import moment from "moment";
import { queryConfig, setDefault } from "@/api/config";
import { runCase } from "@/api/run";

export default {
  name: "Case",
  props: {},
  components: {
    Config,
    Contact,
    Report
  },
  data() {
    return {
      loading: false,

      // 筛选表单属性
      queryForm: {
        name: undefined,
        tag: undefined
      },

      caseTag: [
        { label: "冒烟测试", value: 1 },
        { label: "集成测试", value: 2 },
        { label: "监控脚本", value: 3 }
      ],

      caseEnv: [
        { label: "未知", value: 0, type: "info" },
        { label: "测试", value: 1, type: "primary" },
        { label: "验收", value: 2, type: "success" },
        { label: "预发", value: 3, type: "warning" },
        { label: "生产", value: 4, type: "danger" }
      ],

      // 环境变量数据
      configData: [],
      currentConfigId: "",
      configVisible: false,

      // 表格数据
      tableData: [],
      // 【分页属性】
      pagination: {
        total: 0,
        page: 1,
        pageSize: 11
      },

      groupId: undefined,

      // 【运行接口结果弹窗】
      reportVisible: false,
      caseResult: {
        0: "失败",
        1: "通过",
        2: "未知"
      },
      result: {},

      // * 分组数据 *
      treeData: [],
      children: undefined,
      defaultProps: {
        children: "children",
        label: "label"
      },
      // 新增分组弹窗
      isEdit: false,
      disable: true,
      groupFormTitle: "",
      groupFormVisible: false,
      groupForm: {
        name: "",
        project_id: parseInt(window.localStorage.getItem("projectId")),
        pid: 0
      },

      // 关联接口数据
      contactList: [],
      contactTitle: "",
      contactVisible: true,
      contactForm: {},
      caseId: "",

      // 添加用例弹窗表单数据
      addCaseTitle: "",
      addCaseVisible: false,
      addCaseForm: {
        name: undefined,
        desc: undefined,
        env: undefined,
        tag: undefined,
        config_id: undefined,
        project_id: parseInt(window.localStorage.getItem("projectId")),
        group_id: 1
      },
      addCaseFormrules: {}
    };
  },
  computed: {},
  watch: {},
  created() {
    this.loadGroup();
    this.loadConfig();
    this.loadCase();
  },
  mounted() {},
  methods: {
    // 查询环境变量
    loadConfig() {
      queryConfig({
        project_id: parseInt(window.localStorage.getItem("projectId")),
        page_size: 50
      })
        .then(res => {
          var result = res.data.result;
          this.configData = result;
          for (var config of result) {
            if (config.is_default === true) {
              this.currentConfigId = config.name;
            }
          }
        })
        .catch(err => {
          console.log("错误信息：" + err);
        });
    },

    // 查询关联接口
    loadContract(caseId) {
      queryConnect({
        case_id: caseId
      })
        .then(res => {
          if (res.data.code == 200) {
            this.contactList = res.data.result;
          } else {
            this.$message.error("加载接口步骤失败： " + res.data.msg);
          }
          this.contactVisible = false;
        })
        .catch(err => {
          console.log("错误消息：" + err);
        });
    },

    // 设置默认环境变量
    handleChangeConfig() {
      setDefault({
        project_id: parseInt(window.localStorage.getItem("projectId")),
        id: this.currentConfigId
      })
        .then(res => {
          if (res.data.code == 200) {
            this.$message.success("环境变量设置成功");
          } else {
            this.$message.error("环境变量设置失败" + err);
          }
        })
        .catch(err => {
          this.$message.error("错误消息：" + err);
        });
      this.runTestcaseForm.config_id = this.currentConfigId;
    },

    // tree树结构点击节点回调事件
    handleNodeClick(data, node) {
      this.$nextTick(() => {
        //   节点的id 传进来
        this.$refs.tree.setCurrentKey(data.id);
      });

      this.groupForm.id = data.id;
      this.groupForm.pid = data.pid;
      this.groupForm.name = data.label;

      this.currentGroupName = data.label;
      this.addCaseForm.group_id = data.id;
      this.groupId = data.id;

      this.children = node.childNodes;
      this.disable = true;
      if (data.label !== "默认分组") {
        this.disable = false;
      }
      this.loadCase(1, this.groupId);
    },

    // 加载用例分组数据
    loadGroup() {
      this.disable = true;
      queryGroup({
        project_id: parseInt(window.localStorage.getItem("projectId")),
        page_size: 30
      })
        .then(res => {
          const result = res.data.result;
          this.treeData = result;
          this.getListData();
        })
        .catch(err => {
          console.log("错误消息：" + err);
        });
    },

    // 点击新增分组事件
    handleAddGroup() {
      this.groupFormVisible = true;
      this.isEdit = false;
      this.groupFormTitle = "新增分组";
      this.groupForm.name = "";
    },

    // 点击编辑分组事件
    handleEditGroup() {
      this.groupForm.name = this.currentGroupName;
      this.groupFormVisible = true;
      this.groupFormTitle = "编辑分组";
      this.isEdit = true;
    },

    // 添加分组接口
    addGroup() {
      if (!this.groupForm.id) {
        this.groupForm.pid = 0;
      } else {
        this.groupForm.pid = this.groupForm.id;
        this.groupForm.id = undefined;
      }
      addGroup(this.groupForm)
        .then(res => {
          if (res.data.code === 200) {
            this.$message({
              type: "success",
              message: "新增成功"
            });
          } else {
            this.$message.error("新增失败: " + res.data.msg);
          }
          this.loadGroup();
        })
        .catch(err => {
          this.$message.error("新增失败: " + err);
        });
    },

    // 更新分组接口
    updateGroup() {
      updateGroup(this.groupForm)
        .then(res => {
          if (res.data.code === 200) {
            this.$message({
              type: "success",
              message: "编辑成功"
            });
          } else {
            this.$message.error("编辑失败: " + res.data.msg);
          }
          this.loadGroup();
        })
        .catch(err => {
          this.$message.error("编辑失败: " + err);
        });
    },

    //  提交分组表单
    submitGroupForm() {
      if (!this.isEdit) {
        this.addGroup();
      } else {
        this.updateGroup();
      }
      this.groupFormVisible = false;
    },

    // 删除分组
    deleteGroup(id) {
      if (this.children.length !== 0) {
        this.$message.error("此节点有子级，不可删除！");
        return false;
      } else {
        this.$confirm("是否删除此节点?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            deleteGroup({ id }).then(res => {
              this.$message({
                type: "success",
                message: "删除成功"
              });
            });
            this.loadGroup();
          })
          .catch(err => {
            this.$message({
              type: "info",
              message: "已取消删除"
            });
          });
      }
    },

    handleSizeChange(size) {
      this.pagination.pageSize = size;
      this.loadCase();
    },

    // 查询用例数据
    loadCase(page = 1, group_id = undefined) {
      queryCase({
        page: page,
        page_size: this.pagination.pageSize,
        name: this.queryForm.name,
        tag: this.queryForm.tag,
        group_id: group_id,
        project_id: parseInt(window.localStorage.getItem("projectId"))
      })
        .then(res => {
          this.tableData = res.data.result;
          this.pagination.total = res.data.total;
        })
        .catch(err => {
          console.log("错误消息：" + err);
        });
    },

    // 添加用例按钮
    handleAddCase() {
      this.addCaseVisible = true;
      this.isEdit = false;
      this.addCaseTitle = "添加用例";
      this.addCaseForm = {
        name: "",
        desc: "",
        tag: undefined,
        env: undefined,
        project_id: parseInt(window.localStorage.getItem("projectId")),
        group_id: this.groupId,
        config_id: undefined
      };
    },

    // 编辑用例按钮
    handleonEditCase(index, row) {
      this.addCaseForm = row;
      this.addCaseVisible = true;
      this.isEdit = true;
      this.addCaseTitle = "编辑用例";
    },

    // 新增用例
    addCase() {
      addCase(this.addCaseForm)
        .then(res => {
          if (res.data.code === 200) {
            this.$message({
              type: "success",
              message: "新增成功"
            });
            this.addCaseVisible = false;
            this.loadCase(this.pagination.page);
          } else {
            this.$message.error("新增失败: " + res.data.msg);
          }
        })
        .catch(err => {
          this.$message.error("新增失败: " + err);
        });
    },

    // 更新用例接口
    updateCase() {
      updateCase(this.addCaseForm)
        .then(res => {
          if (res.data.code === 200) {
            this.$message({
              type: "success",
              message: "修改成功"
            });
            this.addCaseVisible = false;
            this.loadCase(this.pagination.page);
          } else {
            this.$message.error("修改失败: " + res.data.msg);
          }
        })
        .catch(err => {
          this.$message.error("修改失败: " + err);
        });
    },

    // 删除用例
    handleDeleteCase(id) {
      {
        this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(() => {
            deleteCase({ id }).then(res => {
              this.$message({
                type: "success",
                message: "删除成功!"
              });
              this.loadCase(this.pagination.page);
            });
          })
          .catch(() => {
            this.$message({
              type: "info",
              message: "已取消删除"
            });
          });
      }
    },

    // 确定按钮
    submitCaseForm() {
      if (!this.isEdit) {
        this.addCase();
      } else {
        this.updateCase();
      }
    },

    // 关联用例
    contactCase(row) {
      this.contactVisible = true;
      this.caseId = row.id;
      this.contactTitle = "关联接口";
      this.loadContract(row.id);
    },

    handleContract() {
      this.contactVisible = true;
    },

    // 运行测试用例
    runCase(index, row) {
      runCase({
        project_id: row.project_id,
        id: row.id,
        config_id: row.config_id
      })
        .then(res => {
          let result = res.data.result;
          if (res.data.code == 200) {
            this.result.status = result.success;
            this.result.interfaceName = result.details[0].name;
            this.result = result;
            this.reportVisible = true;
            this.loadCase(this.pagination.page);
          } else {
            this.$message.error("运行错误: " + res.data.msg);
          }
        })
        .catch(err => {
          console.log("错误信息：" + err);
        });
    },

    // 编写日期格式化方法
    dateFormat: function(row, column) {
      const date = row[column.property];
      if (date === undefined) {
        return "";
      }
      // 这里的格式根据需求修改
      return moment(date).format("YYYY-MM-DD HH:mm:ss");
    },

    // 环境变量确定按钮事件
    handleConfig() {
      this.$refs.config.emitConfig();
      this.configVisible = false;
    },

    // 解析tree数据
    getListData() {
      let dataArray = [];
      this.treeData.forEach(function(data) {
        let pid = data.pid;
        if (pid == 0) {
          let objTemp = {
            id: data.id,
            label: data.name,
            pid: pid
          };
          dataArray.push(objTemp);
        }
      });
      this.data2treeDG(this.treeData, dataArray);
      dataArray.unshift({
        id: 0,
        label: "默认分组",
        pid: 0
      });
    },

    // 解析children数据
    data2treeDG(treeData, dataArray) {
      for (let j = 0; j < dataArray.length; j++) {
        let dataArrayIndex = dataArray[j];
        let childrenArray = [];
        let Id = dataArrayIndex.id;
        for (let i = 0; i < treeData.length; i++) {
          let data = treeData[i];
          let pid = data.pid;
          if (pid == Id) {
            //判断是否为儿子节点
            let objTemp = {
              id: data.id,
              label: data.name,
              pid: pid
            };
            childrenArray.push(objTemp);
          }
        }
        if (childrenArray.length > 0) {
          dataArrayIndex.children = childrenArray;
        }
        if (childrenArray.length > 0) {
          //有儿子节点则递归
          this.data2treeDG(treeData, childrenArray);
        }
      }
      this.treeData = dataArray;
      return dataArray;
    },

    renderContentCont(h, { data }) {
      let createElement = arguments[0];
      return createElement("span", [
        createElement("i", {
          attrs: {
            class: "el-icon-folder",
            style: "font-color:#red;font-size:14px;"
          }
        }),
        createElement("span", "       "),
        createElement("span", arguments[1].node.label)
      ]);
    }
  }
};
</script>

<style lang="less">
::v-deep
  .el-tree--highlight-current
  .el-tree-node.is-current
  > .el-tree-node__content {
  background: #409eff;
}
</style>
